
/* --------------------------------------- Include Files ---------------------------------------- */
//#include "common.h"
#include "stm32f10x.h"
#include "system_timer.h"
#include "uart2.h"

/* ---------------------------------------- Macro Defines --------------------------------------- */
#define Uart2_BAUDRATE_DEFAULT               115200

#define Uart2_RX_RINGBUFFER_SIZE             1600
//#define Uart2_AUX_RX_RINGBUFFER_SIZE         256

/* --------------------------------- Global Function Prototypes --------------------------------- */
void Uart2_initModule(void);
uint32_t Uart2_writeByte(uint8_t data);
uint32_t Uart2_writeBytes(uint8_t *data, uint32_t n_bytes);
uint32_t Uart2_writeString(uint8_t *data_string);
void USART2_IRQHandler(void);
volatile uint32_t Uart2_postRxRingbufferData(uint8_t *data, uint32_t length);
volatile uint32_t Uart2_getRxRingbufferData(uint8_t *data, uint32_t length);
volatile uint32_t Uart2_clearRxRingbufferData(void);
volatile uint32_t Uart2_getRxRingbufferN2RLength(void);
volatile uint32_t Uart2_postAuxRxRingbufferData(uint8_t *data, uint32_t length);
volatile uint32_t Uart2_getAuxRxRingbufferData(uint8_t *data, uint32_t length);
volatile uint32_t Uart2_clearAuxRxRingbufferData(void);
volatile uint32_t Uart2_getAuxRxRingbufferN2RLength(void);
void Uart2_enableAUXBuffer(uint8_t val);

/* -------------------------------------- Static Variables -------------------------------------- */
volatile uint8_t Uart2_rx_ringbuffer[Uart2_RX_RINGBUFFER_SIZE] = {0};
volatile uint32_t Uart2_rx_ringbuffer_n2r = 0;
volatile uint32_t Uart2_rx_ringbuffer_rpt = 0;

//volatile uint8_t Uart2_aux_rx_ringbuffer[Uart2_AUX_RX_RINGBUFFER_SIZE] = {0};
//volatile uint32_t Uart2_aux_rx_ringbuffer_n2r = 0;
//volatile uint32_t Uart2_aux_rx_ringbuffer_rpt = 0;

volatile uint8_t Uart2_aux_buffer_enable = 0x00;
volatile uint32_t Uart2_aux_rxlocker = 1; 
volatile uint8_t uart2_main_buffer_preenable = 0; 


/**
  * @brief Uart2_enableAUXBuffer
  * @param  
  * @retval 
  * @note   
  */
void Uart2_enableAUXBuffer(uint8_t val)
{
    Uart2_aux_buffer_enable = val;
}

void Uart2_preenableMainBuffer(uint32_t val)
{
    uart2_main_buffer_preenable = val;
}

volatile uint32_t Uart2_setRXLocker()
{
    Uart2_aux_rxlocker = 1;
}

volatile uint32_t Uart2_clearRXLocker()
{	
    Uart2_aux_rxlocker = 0;
}

/**
  * @brief Uart2_initModule
  * @param  
  * @retval 
  * @note   
  */
void Uart2_initModule(void)
{
	USART_InitTypeDef USART_InitStructure;

	USART_DeInit(USART2);
	USART_InitStructure.USART_BaudRate            = Uart2_BAUDRATE_DEFAULT;
	USART_InitStructure.USART_WordLength          = USART_WordLength_8b;
	USART_InitStructure.USART_StopBits            = USART_StopBits_1;
	USART_InitStructure.USART_Parity              = USART_Parity_No ;
	USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
	USART_InitStructure.USART_Mode                = USART_Mode_Rx | USART_Mode_Tx;
	USART_Init(USART2, &USART_InitStructure);
	USART_ITConfig(USART2, USART_IT_RXNE, ENABLE);
	USART_ITConfig(USART2, USART_IT_ERR, ENABLE);
	USART_Cmd(USART2, ENABLE);
}

/**
  * @brief Uart2_wrtieByte
  * @param  
  * @retval 
  * @note   
  */
uint32_t Uart2_writeByte(uint8_t data)
{

    while ((USART2->SR & USART_FLAG_TXE) == 0)                       /* Waiting for tx register empty */
    {
    }
    USART2->DR = data;                                               /* Send data */
    return 0x01;
}

/**
  * @brief Uart2_writeBytes
  * @param  
  * @retval 
  * @note   
  */
uint32_t Uart2_writeBytes(uint8_t *data, uint32_t n_bytes)
{
    uint32_t temp = 0;
    uint32_t i = 0;

    for (temp = 0; temp < n_bytes; temp++)                       /* Send data */
    {
        i = Uart2_writeByte(*(data + temp));
        if (i == 0x00)                                           /* Send data failure */
        {
            return (0x00);
        }
    }

    return 0x01;
}

/**
  * @brief Uart2_writeString
  * @param  
  * @retval 
  * @note   
  */
uint32_t Uart2_writeString(uint8_t *data_string)
{
    uint32_t i = 0;

    while (*data_string != 0x00)
    {
        i = Uart2_writeByte(*(data_string++));
        if (i == 0x00)                                     /* Send data failure */
        {
            return (0x00);
        }
    }

    return 0x01;
}

/**
  * @brief USART2_IRQHandler
  * @param  
  * @retval 
  * @note   
  */
void USART2_IRQHandler(void)
{
    uint8_t data = 0;

    /* Read Data from Uart Data Register */
    if (USART_GetITStatus(USART2, USART_IT_RXNE) != RESET)
    {
        data = USART2->DR;
        Uart2_postRxRingbufferData(&data, 1);
    }

    if (USART_GetFlagStatus(USART2, USART_FLAG_ORE) != RESET)
    {
        data = USART2->DR;
        USART_ClearFlag(USART2, USART_FLAG_ORE);
        Uart2_postRxRingbufferData(&data, 1);
    }

    if (USART_GetFlagStatus(USART2, USART_FLAG_NE) != RESET)
    {
        USART_ClearFlag(USART2, USART_FLAG_NE);
    }

    if (USART_GetFlagStatus(USART2, USART_FLAG_FE) != RESET)
    {
        USART_ClearFlag(USART2, USART_FLAG_FE);
    }

    if (USART_GetFlagStatus(USART2, USART_FLAG_PE) != RESET)
    {
        USART_ClearFlag(USART2, USART_FLAG_PE);
    }

}


/**
  * @brief Uart2_postRxRingbufferData
  * @param  
  * @retval 
  * @note   
  */
volatile uint32_t Uart2_postRxRingbufferData(uint8_t *data, uint32_t length)
{
    if (((Uart2_rx_ringbuffer_n2r + length) <= Uart2_RX_RINGBUFFER_SIZE) && (length != 0))
    {
        while (length--)
        {
            Uart2_rx_ringbuffer[(Uart2_rx_ringbuffer_rpt + Uart2_rx_ringbuffer_n2r) % Uart2_RX_RINGBUFFER_SIZE] = *(data++);
            Uart2_rx_ringbuffer_n2r++;
        }
        return 0x01;
    }
    else
    {
        return 0x00;
    }
}

/**
  * @brief Uart2_getRxRingbufferData
  * @param  
  * @retval 
  * @note   
  */
volatile uint32_t Uart2_getRxRingbufferData(uint8_t *data, uint32_t length)
{
    __disable_irq();
    if ((length <= Uart2_rx_ringbuffer_n2r) && (length != 0))
    {
        while (length--)
        {
            *(data++) = Uart2_rx_ringbuffer[Uart2_rx_ringbuffer_rpt];
            Uart2_rx_ringbuffer_rpt = (Uart2_rx_ringbuffer_rpt + 1) % Uart2_RX_RINGBUFFER_SIZE;
            Uart2_rx_ringbuffer_n2r--;
        }
        __enable_irq();
        return 0x01;
    }
    else
    {
        __enable_irq();
        return 0x00;
    }
}

/**
  * @brief Uart2_clearRxRingbufferData
  * @param  
  * @retval 
  * @note   
  */
volatile uint32_t Uart2_clearRxRingbufferData(void)
{
    __disable_irq();
    Uart2_rx_ringbuffer_n2r = 0;
    Uart2_rx_ringbuffer_rpt = 0;
    __enable_irq();
    return 0x01;
}

/**
  * @brief Uart2_getRxRingbufferN2RLength
  * @param  
  * @retval 
  * @note   
  */
volatile uint32_t Uart2_getRxRingbufferN2RLength(void)
{
    return Uart2_rx_ringbuffer_n2r;
}
